Categories
Material UI

Material UI — Expansion Panels Customization and Progress Spinner

Spread the love

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to customize expansion panels and add progress spinner with Material UI.

Additional Actions

We can add additional actions to expansion panels.

For example, we can write:

import React from "react";
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import Checkbox from "@material-ui/core/Checkbox";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Typography from "@material-ui/core/Typography";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";

export default function App() {
  return (
    <div>
      <ExpansionPanel>
        <ExpansionPanelSummary
          expandIcon={<ExpandMoreIcon />}
          id="additional-actions1-header"
        >
          <FormControlLabel
            onClick={event => event.stopPropagation()}
            onFocus={event => event.stopPropagation()}
            control={<Checkbox />}
            label="Lorem ipsum dolor sit amet"
          />
        </ExpansionPanelSummary>
        <ExpansionPanelDetails>
          <Typography>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit
          </Typography>
        </ExpansionPanelDetails>
      </ExpansionPanel>
      <ExpansionPanel>
        <ExpansionPanelSummary
          expandIcon={<ExpandMoreIcon />}
          id="additional-actions2-header"
        >
          <FormControlLabel
            onClick={event => event.stopPropagation()}
            onFocus={event => event.stopPropagation()}
            control={<Checkbox />}
            label="Praesent id erat pretium"
          />
        </ExpansionPanelSummary>
        <ExpansionPanelDetails>
          <Typography>
            Praesent id erat pretium, mollis turpis sit amet, vestibulum ipsum.
            Phasellus non mi eu velit lacinia consequat
          </Typography>
        </ExpansionPanelDetails>
      </ExpansionPanel>
    </div>
  );
}

to add an expansion panel with a checkmark beside the text in the heading.

We nested a ExpansionPanelSummary component to add a checkbox with the FormControlLabel and the Checkbox components.

We’ve to add event handlers for the onClick and onFocus props in the FormControlLabel s so that the click events of the checkboxes won’t propagate to the expansion panel summary.

Secondary Heading and Columns

We can add whatever we want into the headings and content.

So we can add secondary headings if we want.

To do that, we can write:

import React from "react";
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelActions from "@material-ui/core/ExpansionPanelActions";
import Typography from "@material-ui/core/Typography";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import Button from "@material-ui/core/Button";
import Divider from "@material-ui/core/Divider";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  column: {
    flexBasis: "33.33%"
  }
}));

export default function App() {
  const classes = useStyles();

  return (
    <div>
      <ExpansionPanel defaultExpanded>
        <ExpansionPanelSummary
          expandIcon={<ExpandMoreIcon />}
          id="panel1c-header"
        >
          <div className={classes.column}>
            <Typography>Fruits</Typography>
          </div>
          <div className={classes.column}>
            <Typography>choose a fruit</Typography>
          </div>
        </ExpansionPanelSummary>
        <ExpansionPanelDetails>
          <div>
            <Typography variant="caption">apple, orange</Typography>
          </div>
        </ExpansionPanelDetails>
        <Divider />
        <ExpansionPanelActions>
          <Button size="small">Cancel</Button>
          <Button size="small" color="primary">
            Save
          </Button>
        </ExpansionPanelActions>
      </ExpansionPanel>
    </div>
  );
}

We add some text that is divided into columns.

The className are set so that we can see stuff side by side.

Also, we used the ExpansionPanelActions component to add some buttons into its own container.

The Divider is displayed as a line between the ExpansionPanelDetails and ExpansionPanelActions .

Progress Indicators

To show that something is loading, we can add a progress indicator to our app.

For example, we can use the CircularProgress component to show the loading spinner.

We can write:

import React from "react";
import CircularProgress from "@material-ui/core/CircularProgress";

export default function App() {
  return (
    <div>
      <CircularProgress />
    </div>
  );
}

to add a circular spinner.

We can change the color with the color :

import React from "react";
import CircularProgress from "@material-ui/core/CircularProgress";

export default function App() {
  return (
    <div>
      <CircularProgress color="secondary" />
    </div>
  );
}

Circular Determinate

We can display a circular progress spinner to display the spinner only when something is loading.

For instance, we can write:

import React from "react";
import CircularProgress from "@material-ui/core/CircularProgress";

export default function App() {
  const [progress, setProgress] = React.useState(0);

  React.useEffect(() => {
    const timer = setInterval(() => {
      setProgress(prevProgress =>
        prevProgress >= 100 ? 0 : prevProgress + 10
      );
    }, 800);

    return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <div>
      <CircularProgress variant="static" value={progress} />
    </div>
  );
}

We add the CircularProgress component with the variant set to static to make it static.

This lets us update the spinner display when the progress state updates.

Conclusion

We can customize our expansion panels with the content that we want.

Also, we can add a progress spinner that displays as an uncontrolled component.

Or we can animate it according to the progress of something.

The styling of everything can be customized.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *